<?php
/**
 * Application is the base class for all application classes.
 *
 * @copyright Copyright (c) 2015 Swolf Software.
 * @author liuxiao<seanliu707@gmail.com>
 */
class Application
{
	/**
	 * @var string the application name.
	 */
	public $name = 'Hpcer';
	/**
	 * @var string the version of this application.
	 */
	public $version = '1.0';
	/**
	 * @var string the charset currently used for the application.
	 */
	public $charset = 'UTF-8';
	/**
	 * @var string the language that is meant to be used for end users. It is recommended that you
	 */
	public $language = 'en-US';
	
	protected static $_config = null;
	
	public function __construct(&$config)
	{
		$_arr = array();
		if (!empty($config)) {
			foreach ($config as $value) {
				$_arr = array_merge($_arr, $value);
			}
		} 
		static::$_config = $_arr;
		
	}
	
	/**
	 * Runs the application.
	 * This is the main entrance of an application.
	 * @return integer the exit status (0 means normal, non-zero values mean abnormal)
	 */
	public function run()
	{
		//parse the URL:
		$uri = Swolf::createObject('base/UrlManager');
		
		$_request_params = $uri->parseUrl();
		
		//whether compress the transfer data and handle the request
		if (isset(static::$_config['gzip'])
				&& static::$_config['gzip'] != false
				&& isset($_SERVER['HTTP_ACCEPT_ENCODING'])
                && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE) {
			ob_start('ob_gzip');
			$this->handleRequest($_request_params);
			ob_end_flush();
		} else {	//handle the request only
			$this->handleRequest($_request_params);
		}
	}
	
	/**
	 * Get the controller instance.
	 * 
	 * @param string $controller like 'index'
	 */
	private function getController($cotroller = '')
	{
		$_ctl_file = null;
		$_arr = array();
		
		$cotroller = (string) $cotroller;
		if (empty($cotroller)) {	//set default controller: 'main/index'.
			$cotroller = 'main/index';
		}
		
		$_arr = explode('/', $cotroller);
		$className = ucfirst($_arr[0].'Controller');
		$_ctl_file = static::$_config['ctrPath'] . $className . '.php';
		
		//Require the specified controller file and creat the object of the controller.
		if (file_exists($_ctl_file)) {
			Swolf::load('base.Controller');
			require $_ctl_file;	
		}
		
		$ctl = new $className;
		
		//return the module.
		if (method_exists($ctl, $_arr[1])) {
		    return $ctl->$_arr[1]();
		} else {
		    exit('This module doesnt exists.');
		}
	}
	
	/**
	 * Handles the specified request.
	 *
	 * This method should return an instance of Response or its child class
	 * which represents the handling result of the request.
	 *
	 * @param Request $request the request to be handled
	 * @return Response the resulting response
	 */
	private function handleRequest($request)
	{
		$_controller = '';
		
		//Get the specified controller and instantiates it:
		if (is_array($request) && isset($request['mp'])) {
				$_controller = $request['mp'];
		} elseif (is_string($request)) {
			$_arr = explode($request, '/');
			if (count($_arr) > 1) {
				$_controller = $_arr[0].'/'.$_arr[1];
			}
		}
		
		$this->getController($_controller);
	}
	
	/**
	 * Get configuration information
	 * 
	 * @param  string $con
	 *         for instance, 'static.img'
	 * 
	 * @return array
	 */
	public static function getConfig($con = '')
	{
	    if ($con == '') {
	        return static::$_config;
	    } else {
	        if (stripos($con, '.') !== false) {
	            $arr = explode('.', $con);
	            $n = count($arr);
	            $re = array();
	            
	            switch ($n) {
	                case 1:
	                    $re = static::$_config[$arr[0]];
	                    break;
	                case 2:
	                    $re = static::$_config[$arr[0]][$arr[1]];
	                    break;
	                case 3:
	                    $re = static::$_config[$arr[0]][$arr[1]][$arr[2]];
	                    break;
	            }
	            
	            if (isset($re)) {
	                return $re;
	            }
	            return FALSE;
	        }
	        
	        if (isset(static::$_config[$con])) {
    			return static::$_config[$con];
	        }
	        
	        return FALSe;
		}
	}
	
	//------------------------------------components---------------------------------------------
	
	/**
	 * Returns the cache component.
	 * @return CacheFactory the cache application component. Null if the component is not enabled.
	 */
	public function getCache()
	{
		return Swolf::load('caching.CacheFactory');
	}
	
	
	/**
	 * Returns the mailer component.
	 * @return \yii\mail\MailerInterface the mailer application component.
	 */
	public function getMailer()
	{
	}
	
	/**
	 * Returns the asset manager.
	 * @return \yii\web\AssetManager the asset manager application component.
	 */
	public function getAssetManager()
	{
	}
	
	/**
	 * Returns the security component.
	 * @return \yii\base\Security the security application component.
	 */
	public function getSecurity()
	{
	}
	
	/**
	 * Terminates the application.
	 * This method replaces the `exit()` function by ensuring the application life cycle is completed
	 * before terminating the application.
	 * @param integer $status the exit status (value 0 means normal exit while other values mean abnormal exit).
	 * @param Response $response the response to be sent. If not set, the default application [[response]] component will be used.
	 * @throws ExitException if the application is in testing mode
	 */
	public function end($status = 0, $response = null)
	{
		
	}
}

/**
 * Transfer compress function.
 * this is the callback function for ob_start
 * @param $_buffer
 */
function ob_gzip($_buffer)
{
	$_buffer = gzencode($_buffer, 9);
	header("Content-Encoding: gzip");
	header("Vary: Accept-Encoding");
	header("Content-Length: ".strlen($_buffer));
	return $_buffer;
}